---
title: Form Control
package: "@chakra-ui/form-control"
description:
  Form Control provides context such as isInvalid, isDisabled, and isRequired to
  form elements
---

FormControl provides context such as `isInvalid`, `isDisabled`, and `isRequired`
to form elements.

It follows the [WAI specifications](https://www.w3.org/WAI/tutorials/forms/) for
forms.

<ComponentLinks
  theme={{ componentName: "form" }}
  github={{ package: "form-control" }}
  npm={{ package: "@chakra-ui/form-control" }}
/>

<carbon-ad></carbon-ad>

## Import

```js
import {
  FormControl,
  FormLabel,
  FormErrorMessage,
  FormHelperText,
} from "@chakra-ui/react"
```

## Usage

```jsx
<FormControl id="email">
  <FormLabel>Email address</FormLabel>
  <Input type="email" />
  <FormHelperText>We'll never share your email.</FormHelperText>
</FormControl>
```

### Sample usage for a radio or checkbox group

```jsx
<FormControl as="fieldset">
  <FormLabel as="legend">Favorite Naruto Character</FormLabel>
  <RadioGroup defaultValue="Itachi">
    <HStack spacing="24px">
      <Radio value="Sasuke">Sasuke</Radio>
      <Radio value="Nagato">Nagato</Radio>
      <Radio value="Itachi">Itachi</Radio>
      <Radio value="Sage of the six Paths">Sage of the six Paths</Radio>
    </HStack>
  </RadioGroup>
  <FormHelperText>Select only if you're a fan.</FormHelperText>
</FormControl>
```

### Making a field required

By passing the `isRequired` props, the `Input` field has `aria-required` set to
`true`, and the `FormLabel` will show a red asterisk.

```jsx
<FormControl id="first-name" isRequired>
  <FormLabel>First name</FormLabel>
  <Input placeholder="First name" />
</FormControl>
```

### Select Example

```jsx
<FormControl id="country">
  <FormLabel>Country</FormLabel>
  <Select placeholder="Select country">
    <option>United Arab Emirates</option>
    <option>Nigeria</option>
  </Select>
</FormControl>
```

### Number Input Example

```jsx
<FormControl id="amount">
  <FormLabel>Amount</FormLabel>
  <NumberInput max={50} min={10}>
    <NumberInputField />
    <NumberInputStepper>
      <NumberIncrementStepper />
      <NumberDecrementStepper />
    </NumberInputStepper>
  </NumberInput>
</FormControl>
```

### Usage with Form Libraries

Form Libraries like [Formik](https://jaredpalmer.com/formik/) make it soooo easy
to manage form state and validation. I 💖 Formik

```jsx
function FormikExample() {
  function validateName(value) {
    let error
    if (!value) {
      error = "Name is required"
    } else if (value.toLowerCase() !== "naruto") {
      error = "Jeez! You're not a fan 😱"
    }
    return error
  }

  return (
    <Formik
      initialValues={{ name: "Sasuke" }}
      onSubmit={(values, actions) => {
        setTimeout(() => {
          alert(JSON.stringify(values, null, 2))
          actions.setSubmitting(false)
        }, 1000)
      }}
    >
      {(props) => (
        <Form>
          <Field name="name" validate={validateName}>
            {({ field, form }) => (
              <FormControl isInvalid={form.errors.name && form.touched.name}>
                <FormLabel htmlFor="name">First name</FormLabel>
                <Input {...field} id="name" placeholder="name" />
                <FormErrorMessage>{form.errors.name}</FormErrorMessage>
              </FormControl>
            )}
          </Field>
          <Button
            mt={4}
            colorScheme="teal"
            isLoading={props.isSubmitting}
            type="submit"
          >
            Submit
          </Button>
        </Form>
      )}
    </Formik>
  )
}
```

## Improvements from v1

- We've improved the accessibility of the `FormControl` component. Here are the
  changes:

  - `id` passed to the form control will be passed to the form input directly.
  - `FormLabel` will have `htmlFor` that points to the `id` of the form input.
  - `FormErrorMessage` adds `aria-describedby` and `aria-invalid` pointing to
    the form input.
  - `FormHelperText` adds/extends `aria-describedby` pointing to the form input.
  - `isDisabled`, `isRequired`, `isReadOnly` props passed to `FormControl` will
    cascade across all related components.

- `FormLabel` is now aware of the `disabled`, `focused` and `error` state of the
  form input. This helps you style the label accordingly using the `_disabled`,
  `_focus`, and `_invalid` style props.

- If you render `FormErrorMessage` and `isInvalid` is `false` or `undefined`,
  `FormErrorMessage` won't be visible. The only way to make it visible is by
  passing `isInvalid` and setting it to `true`.

## Props

<PropsTable of="FormControl" />
